/*      */ package com.zimbra.cs.index;
/*      */ 
/*      */ import com.google.common.base.Joiner;
/*      */ import com.google.common.base.Objects;
/*      */ import com.google.common.base.Objects.ToStringHelper;
/*      */ import com.google.common.base.Strings;
/*      */ import com.google.common.base.Supplier;
/*      */ import com.google.common.collect.Iterables;
/*      */ import com.google.common.collect.Multimap;
/*      */ import com.google.common.collect.Multimaps;
/*      */ import com.google.common.collect.Sets;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.util.ListUtil;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.mailbox.Flag;
/*      */ import com.zimbra.cs.mailbox.Folder;
/*      */ import com.zimbra.cs.mailbox.MailItem.Type;
/*      */ import com.zimbra.cs.mailbox.Mailbox;
/*      */ import com.zimbra.cs.mailbox.Mountpoint;
/*      */ import com.zimbra.cs.mailbox.Tag;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Collection;
/*      */ import java.util.Collections;
/*      */ import java.util.EnumMap;
/*      */ import java.util.EnumSet;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.List;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public abstract interface DbSearchConstraints
/*      */   extends Cloneable
/*      */ {
/*      */   public abstract void ensureSpamTrashSetting(Mailbox paramMailbox, List<Folder> paramList)
/*      */     throws ServiceException;
/*      */   
/*      */   public abstract boolean hasSpamTrashSetting();
/*      */   
/*      */   public abstract void forceHasSpamTrashSetting();
/*      */   
/*      */   public abstract DbSearchConstraints and(DbSearchConstraints paramDbSearchConstraints);
/*      */   
/*      */   public abstract DbSearchConstraints or(DbSearchConstraints paramDbSearchConstraints);
/*      */   
/*      */   public abstract boolean hasNoResults();
/*      */   
/*      */   public abstract boolean tryDbFirst(Mailbox paramMailbox)
/*      */     throws ServiceException;
/*      */   
/*      */   public abstract void setTypes(Set<MailItem.Type> paramSet);
/*      */   
/*      */   public abstract DbSearchConstraints optimize();
/*      */   
/*      */   public abstract boolean isEmpty();
/*      */   
/*      */   public abstract Object clone();
/*      */   
/*      */   public abstract StringBuilder toQueryString(StringBuilder paramStringBuilder);
/*      */   
/*      */   public abstract List<DbSearchConstraints> getChildren();
/*      */   
/*      */   public abstract Leaf toLeaf();
/*      */   
/*      */   public static final class Leaf
/*      */     implements DbSearchConstraints, Cloneable
/*      */   {
/*      */     public boolean isEmpty()
/*      */     {
/*  147 */       if ((this.tags.isEmpty()) && (this.excludeTags.isEmpty()) && (this.folders.isEmpty()) && (this.excludeFolders.isEmpty()) && (this.types.isEmpty()) && (this.typesFactoredOut) && (this.convId == 0) && (this.prohibitedConvIds.isEmpty()) && (this.itemIds.isEmpty()) && (this.prohibitedItemIds.isEmpty()) && (this.hasIndexId == null) && (!this.excludeHasRecipients) && (this.ranges.isEmpty()) && (this.cursorRange == null))
/*      */       {
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  162 */         return true;
/*      */       }
/*  164 */       return false;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */     public Leaf optimize()
/*      */     {
/*  171 */       return this;
/*      */     }
/*      */     
/*      */     public List<DbSearchConstraints> getChildren()
/*      */     {
/*  176 */       return null;
/*      */     }
/*      */     
/*      */     public Leaf toLeaf()
/*      */     {
/*  181 */       return this;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  188 */     public boolean noResults = false;
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  193 */     public final Set<Tag> tags = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  196 */     public final Set<Tag> excludeTags = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  199 */     public final Set<Folder> folders = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  202 */     public final Set<Folder> excludeFolders = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  205 */     public final Set<DbSearchConstraints.RemoteFolderDescriptor> remoteFolders = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  208 */     public final Set<DbSearchConstraints.RemoteFolderDescriptor> excludeRemoteFolders = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  211 */     public int convId = 0;
/*      */     
/*      */ 
/*  214 */     public final Set<Integer> prohibitedConvIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*      */     public ItemId remoteConvId;
/*      */     
/*      */ 
/*  220 */     public final Set<ItemId> prohibitedRemoteConvIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  223 */     public final Set<Integer> itemIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  226 */     public final Set<Integer> prohibitedItemIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  229 */     public final Set<ItemId> remoteItemIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  232 */     public final Set<ItemId> prohibitedRemoteItemIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*  235 */     public final Set<Integer> indexIds = Sets.newHashSetWithExpectedSize(0);
/*      */     
/*      */ 
/*      */     public Boolean hasIndexId;
/*      */     
/*      */ 
/*  241 */     public final Set<MailItem.Type> types = EnumSet.noneOf(MailItem.Type.class);
/*      */     
/*      */ 
/*  244 */     public final Set<MailItem.Type> excludeTypes = EnumSet.noneOf(MailItem.Type.class);
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  249 */     public final Multimap<DbSearchConstraints.RangeType, DbSearchConstraints.Range> ranges = Multimaps.newMultimap(new EnumMap(DbSearchConstraints.RangeType.class), new Supplier()
/*      */     {
/*      */       public Set<DbSearchConstraints.Range> get()
/*      */       {
/*  253 */         return new HashSet();
/*      */       }
/*  249 */     });
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     public DbSearchConstraints.CursorRange cursorRange;
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  259 */     public boolean typesFactoredOut = false;
/*  260 */     public boolean excludeHasRecipients = false;
/*      */     
/*      */     private Set<MailItem.Type> calcTypes() {
/*  263 */       if (this.excludeTypes.isEmpty()) {
/*  264 */         return this.types;
/*      */       }
/*  266 */       if (this.types.isEmpty()) {
/*  267 */         this.types.addAll(EnumSet.allOf(MailItem.Type.class));
/*  268 */         this.types.remove(MailItem.Type.UNKNOWN);
/*      */       }
/*  270 */       for (MailItem.Type type : this.excludeTypes) {
/*  271 */         this.types.remove(type);
/*      */       }
/*  273 */       this.excludeTypes.clear();
/*  274 */       return this.types;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */     public boolean hasNonAppointmentTypes()
/*      */     {
/*  281 */       Set<MailItem.Type> types = EnumSet.copyOf(calcTypes());
/*  282 */       types.remove(MailItem.Type.APPOINTMENT);
/*  283 */       types.remove(MailItem.Type.TASK);
/*  284 */       return !types.isEmpty();
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */     public boolean hasAppointmentTableConstraints()
/*      */     {
/*  291 */       Set<MailItem.Type> types = calcTypes();
/*  292 */       return ((this.ranges.containsKey(DbSearchConstraints.RangeType.CAL_START_DATE)) || (this.ranges.containsKey(DbSearchConstraints.RangeType.CAL_END_DATE))) && ((types.contains(MailItem.Type.APPOINTMENT)) || (types.contains(MailItem.Type.TASK)));
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */     public Folder getOnlyFolder()
/*      */     {
/*  301 */       if ((this.folders.size() == 1) && (this.excludeFolders.isEmpty()) && (this.indexIds.isEmpty()) && (this.ranges.isEmpty()) && (this.types.contains(MailItem.Type.MESSAGE)) && (!this.excludeTypes.contains(MailItem.Type.MESSAGE)) && (this.tags.isEmpty()) && (this.excludeTags.isEmpty()) && (this.convId == 0) && (this.prohibitedConvIds.isEmpty()) && (this.itemIds.isEmpty()) && (this.prohibitedItemIds.isEmpty()))
/*      */       {
/*      */ 
/*      */ 
/*  305 */         return (Folder)Iterables.getOnlyElement(this.folders);
/*      */       }
/*  307 */       return null;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */     public Boolean getIsSoloPart()
/*      */     {
/*  321 */       Collection<DbSearchConstraints.Range> convCountRanges = this.ranges.get(DbSearchConstraints.RangeType.CONV_COUNT);
/*  322 */       if (convCountRanges.size() != 1) {
/*  323 */         return null;
/*      */       }
/*  325 */       DbSearchConstraints.NumericRange range = (DbSearchConstraints.NumericRange)Iterables.getOnlyElement(convCountRanges);
/*  326 */       if ((range.max == 1L) && (range.maxInclusive) && (range.min == 1L) && (range.minInclusive)) {
/*  327 */         return Boolean.valueOf(range.bool);
/*      */       }
/*  329 */       return null;
/*      */     }
/*      */     
/*      */ 
/*      */     public Leaf clone()
/*      */     {
/*  335 */       Leaf result = new Leaf();
/*  336 */       result.tags.addAll(this.tags);
/*  337 */       result.excludeTags.addAll(this.excludeTags);
/*  338 */       result.folders.addAll(this.folders);
/*  339 */       result.excludeFolders.addAll(this.excludeFolders);
/*  340 */       result.remoteFolders.addAll(this.remoteFolders);
/*  341 */       result.excludeRemoteFolders.addAll(this.excludeRemoteFolders);
/*  342 */       result.convId = this.convId;
/*  343 */       result.prohibitedConvIds.addAll(this.prohibitedConvIds);
/*  344 */       result.remoteConvId = this.remoteConvId;
/*  345 */       result.prohibitedRemoteConvIds.addAll(this.prohibitedRemoteConvIds);
/*  346 */       result.itemIds.addAll(this.itemIds);
/*  347 */       result.prohibitedItemIds.addAll(this.prohibitedItemIds);
/*  348 */       result.remoteItemIds.addAll(this.remoteItemIds);
/*  349 */       result.prohibitedRemoteItemIds.addAll(this.prohibitedRemoteItemIds);
/*  350 */       result.indexIds.addAll(this.indexIds);
/*  351 */       result.types.addAll(this.types);
/*  352 */       result.excludeTypes.addAll(this.excludeTypes);
/*  353 */       for (Map.Entry<DbSearchConstraints.RangeType, DbSearchConstraints.Range> entry : this.ranges.entries()) {
/*  354 */         result.ranges.put(entry.getKey(), ((DbSearchConstraints.Range)entry.getValue()).clone());
/*      */       }
/*  356 */       return result;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */     private String quoteIfNecessary(String name)
/*      */     {
/*  366 */       if (name.indexOf(" ") < 0) {
/*  367 */         return name;
/*      */       }
/*  369 */       String quoted = "\"" + name.replaceAll("\"", "\\\\\"") + "\"";
/*  370 */       return quoted;
/*      */     }
/*      */     
/*      */     public StringBuilder toQueryString(StringBuilder out)
/*      */     {
/*  375 */       if (this.noResults) {
/*  376 */         out.append("-IS:anywhere ");
/*  377 */         return out;
/*      */       }
/*  379 */       if (!this.tags.isEmpty()) {
/*  380 */         out.append("TAG:(");
/*  381 */         List<String> list = new ArrayList(this.tags.size());
/*  382 */         for (Tag tag : this.tags) {
/*  383 */           list.add(quoteIfNecessary(tag.getName()));
/*      */         }
/*  385 */         Joiner.on(' ').appendTo(out, list);
/*  386 */         out.append(") ");
/*      */       }
/*  388 */       if (!this.excludeTags.isEmpty()) {
/*  389 */         out.append("-TAG:(");
/*  390 */         List<String> list = new ArrayList(this.excludeTags.size());
/*  391 */         for (Tag tag : this.excludeTags) {
/*  392 */           list.add(quoteIfNecessary(tag.getName()));
/*      */         }
/*  394 */         Joiner.on(' ').appendTo(out, list);
/*  395 */         out.append(") ");
/*      */       }
/*  397 */       for (Folder folder : this.folders) {
/*  398 */         if ((folder instanceof Mountpoint)) {
/*  399 */           out.append("INID:").append(((Mountpoint)folder).getRemoteId()).append(' ');
/*      */         } else {
/*  401 */           out.append("IN:").append(folder.getPath()).append(' ');
/*      */         }
/*      */       }
/*  404 */       for (Folder folder : this.excludeFolders) {
/*  405 */         if ((folder instanceof Mountpoint)) {
/*  406 */           out.append("-INID:").append(((Mountpoint)folder).getRemoteId()).append(' ');
/*      */         } else {
/*  408 */           out.append("-ID:").append(folder.getPath()).append(' ');
/*      */         }
/*      */       }
/*  411 */       for (DbSearchConstraints.RemoteFolderDescriptor folder : this.remoteFolders) {
/*  412 */         out.append(folder.includeSubfolders ? "UNDERID:\"" : "INID:\"");
/*  413 */         out.append(folder.getFolderId());
/*  414 */         if (!Strings.isNullOrEmpty(folder.getSubfolderPath())) {
/*  415 */           out.append('/').append(folder.getSubfolderPath());
/*      */         }
/*  417 */         out.append("\" ");
/*      */       }
/*  419 */       for (DbSearchConstraints.RemoteFolderDescriptor folder : this.excludeRemoteFolders) {
/*  420 */         out.append(folder.includeSubfolders ? "UNDERID:\"" : "INID:\"");
/*  421 */         out.append(folder.getFolderId());
/*  422 */         if (!Strings.isNullOrEmpty(folder.getSubfolderPath())) {
/*  423 */           out.append('/').append(folder.getSubfolderPath());
/*      */         }
/*  425 */         out.append("\" ");
/*      */       }
/*  427 */       if (this.convId != 0) {
/*  428 */         out.append("CONV:").append(this.convId).append(' ');
/*      */       }
/*  430 */       if (!this.prohibitedConvIds.isEmpty()) {
/*  431 */         out.append("-CONV:(");
/*  432 */         Joiner.on(' ').appendTo(out, this.prohibitedConvIds);
/*  433 */         out.append(") ");
/*      */       }
/*  435 */       if (this.remoteConvId != null) {
/*  436 */         out.append("CONV:\"").append(this.remoteConvId).append("\" ");
/*      */       }
/*  438 */       if (!this.prohibitedRemoteConvIds.isEmpty()) {
/*  439 */         out.append("-CONV:(");
/*  440 */         Joiner.on(' ').appendTo(out, this.prohibitedRemoteConvIds);
/*  441 */         out.append(") ");
/*      */       }
/*  443 */       if (!this.itemIds.isEmpty()) {
/*  444 */         out.append("ITEM:(");
/*  445 */         Joiner.on(' ').appendTo(out, this.itemIds);
/*  446 */         out.append(") ");
/*      */       }
/*  448 */       if (!this.prohibitedItemIds.isEmpty()) {
/*  449 */         out.append("-ITEM:(");
/*  450 */         Joiner.on(' ').appendTo(out, this.prohibitedItemIds);
/*  451 */         out.append(") ");
/*      */       }
/*  453 */       for (ItemId id : this.remoteItemIds) {
/*  454 */         out.append("ITEM:\"").append(id).append("\" ");
/*      */       }
/*  456 */       for (ItemId id : this.prohibitedRemoteItemIds) {
/*  457 */         out.append("-ITEM:\"").append(id).append("\" ");
/*      */       }
/*  459 */       if (!this.indexIds.isEmpty()) {
/*  460 */         out.append("INDEXID:(");
/*  461 */         Joiner.on(' ').appendTo(out, this.indexIds);
/*  462 */         out.append(") ");
/*      */       }
/*  464 */       if (this.hasIndexId != null) {
/*  465 */         out.append(this.hasIndexId.booleanValue() ? "HAS_INDEXID" : "-HAS_INDEXID");
/*      */       }
/*  467 */       if (!this.types.isEmpty()) {
/*  468 */         out.append("ITEM_TYPE:(");
/*  469 */         Joiner.on(' ').appendTo(out, this.types);
/*  470 */         out.append(") ");
/*      */       }
/*  472 */       if (!this.excludeTypes.isEmpty()) {
/*  473 */         out.append("-ITEM_TYPE:(");
/*  474 */         Joiner.on(' ').appendTo(out, this.excludeTypes);
/*  475 */         out.append(") ");
/*      */       }
/*  477 */       for (Map.Entry<DbSearchConstraints.RangeType, DbSearchConstraints.Range> entry : this.ranges.entries()) {
/*  478 */         ((DbSearchConstraints.Range)entry.getValue()).toQueryString(((DbSearchConstraints.RangeType)entry.getKey()).toQuery(), out).append(' ');
/*      */       }
/*  480 */       return out;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */     public void and(Leaf other)
/*      */     {
/*  487 */       if ((this.noResults) || (other.noResults)) {
/*  488 */         this.noResults = true;
/*  489 */         return;
/*      */       }
/*  491 */       this.tags.addAll(other.tags);
/*  492 */       this.excludeTags.addAll(other.excludeTags);
/*      */       
/*      */ 
/*  495 */       if (!Collections.disjoint(this.tags, this.excludeTags)) {
/*  496 */         this.noResults = true;
/*  497 */         return;
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  504 */       if (!other.folders.isEmpty()) {
/*  505 */         if (this.folders.isEmpty()) {
/*  506 */           this.folders.addAll(other.folders);
/*      */         } else {
/*  508 */           this.folders.retainAll(other.folders);
/*  509 */           if (this.folders.isEmpty()) {
/*  510 */             this.noResults = true;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*  515 */       this.excludeFolders.addAll(other.excludeFolders);
/*      */       
/*      */ 
/*      */ 
/*  519 */       this.remoteFolders.addAll(other.remoteFolders);
/*  520 */       this.excludeRemoteFolders.addAll(other.excludeRemoteFolders);
/*      */       
/*  522 */       if (other.convId != 0) {
/*  523 */         if (this.convId != 0) {
/*  524 */           if (this.convId != other.convId) {
/*  525 */             ZimbraLog.index.debug("ANDING a constraint with incompatible convIds, this is a NO_RESULTS constraint now");
/*  526 */             this.noResults = true;
/*      */           }
/*      */         } else {
/*  529 */           this.convId = other.convId;
/*      */         }
/*      */       }
/*  532 */       this.prohibitedConvIds.addAll(other.prohibitedConvIds);
/*      */       
/*  534 */       if (other.remoteConvId != null) {
/*  535 */         if (this.remoteConvId != null) {
/*  536 */           if (!this.remoteConvId.equals(other.remoteConvId)) {
/*  537 */             ZimbraLog.index.debug("ANDING a constraint with incompatible remoteConvIds, this is a NO_RESULTS constraint now");
/*  538 */             this.noResults = true;
/*      */           }
/*      */         } else {
/*  541 */           this.remoteConvId = other.remoteConvId;
/*      */         }
/*      */       }
/*  544 */       this.prohibitedRemoteConvIds.addAll(other.prohibitedRemoteConvIds);
/*      */       
/*      */ 
/*      */ 
/*  548 */       if (!other.itemIds.isEmpty()) {
/*  549 */         if (this.itemIds.isEmpty()) {
/*  550 */           this.itemIds.addAll(other.itemIds);
/*      */         } else {
/*  552 */           this.itemIds.retainAll(other.itemIds);
/*  553 */           if (this.itemIds.isEmpty()) {
/*  554 */             this.noResults = true;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  563 */       this.prohibitedItemIds.addAll(other.prohibitedItemIds);
/*      */       
/*      */ 
/*      */ 
/*  567 */       if (!other.remoteItemIds.isEmpty()) {
/*  568 */         if (this.remoteItemIds.isEmpty()) {
/*  569 */           this.remoteItemIds.addAll(other.remoteItemIds);
/*      */         } else {
/*  571 */           this.remoteItemIds.retainAll(other.remoteItemIds);
/*  572 */           if (this.remoteItemIds.isEmpty()) {
/*  573 */             this.noResults = true;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  582 */       this.prohibitedRemoteItemIds.addAll(other.prohibitedRemoteItemIds);
/*      */       
/*      */ 
/*  585 */       if (!other.indexIds.isEmpty()) {
/*  586 */         if (this.indexIds.isEmpty()) {
/*  587 */           this.indexIds.addAll(other.indexIds);
/*      */         } else {
/*  589 */           this.indexIds.retainAll(other.indexIds);
/*  590 */           if (this.indexIds.isEmpty()) {
/*  591 */             this.noResults = true;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*  596 */       if (this.hasIndexId == null) {
/*  597 */         this.hasIndexId = other.hasIndexId;
/*  598 */       } else if ((other.hasIndexId != null) && 
/*  599 */         (!this.hasIndexId.equals(other.hasIndexId))) {
/*  600 */         this.noResults = true;
/*  601 */         ZimbraLog.index.debug("Adding a HAS_NO_INDEXIDS constraint to a HAS_INDEXIDS one, this is a NO_RESULTS result");
/*  602 */         return;
/*      */       }
/*      */       
/*      */ 
/*  606 */       if (!other.types.isEmpty()) {
/*  607 */         if (this.types.isEmpty()) {
/*  608 */           this.types.addAll(other.types);
/*      */         } else {
/*  610 */           this.types.retainAll(other.types);
/*  611 */           if (this.types.isEmpty()) {
/*  612 */             this.noResults = true;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*  617 */       this.excludeTypes.addAll(other.excludeTypes);
/*  618 */       this.ranges.putAll(other.ranges);
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  629 */     protected boolean mHasSpamTrashSetting = false;
/*      */     
/*      */     public void ensureSpamTrashSetting(Mailbox mbox, List<Folder> trashSpamFolders)
/*      */     {
/*  633 */       if (!this.mHasSpamTrashSetting) {
/*  634 */         for (Folder f : trashSpamFolders) {
/*  635 */           this.excludeFolders.add(f);
/*      */         }
/*  637 */         this.mHasSpamTrashSetting = true;
/*      */       }
/*      */     }
/*      */     
/*      */     public DbSearchConstraints and(DbSearchConstraints other)
/*      */     {
/*  643 */       if ((other instanceof DbSearchConstraints.Intersection))
/*  644 */         return other.and(this);
/*  645 */       if ((other instanceof DbSearchConstraints.Union)) {
/*  646 */         return other.and(this);
/*      */       }
/*  648 */       if (other.hasSpamTrashSetting()) {
/*  649 */         forceHasSpamTrashSetting();
/*      */       }
/*  651 */       if (other.hasNoResults()) {
/*  652 */         this.noResults = true;
/*      */       }
/*  654 */       and((Leaf)other);
/*  655 */       return this;
/*      */     }
/*      */     
/*      */ 
/*      */     public DbSearchConstraints or(DbSearchConstraints other)
/*      */     {
/*  661 */       if ((other instanceof DbSearchConstraints.Union)) {
/*  662 */         return other.or(this);
/*      */       }
/*  664 */       DbSearchConstraints top = new DbSearchConstraints.Union();
/*  665 */       return top.or(this).or(other);
/*      */     }
/*      */     
/*      */ 
/*      */     public boolean hasSpamTrashSetting()
/*      */     {
/*  671 */       return this.mHasSpamTrashSetting;
/*      */     }
/*      */     
/*      */     public void forceHasSpamTrashSetting()
/*      */     {
/*  676 */       this.mHasSpamTrashSetting = true;
/*      */     }
/*      */     
/*      */     public boolean hasNoResults()
/*      */     {
/*  681 */       return this.noResults;
/*      */     }
/*      */     
/*      */     public boolean tryDbFirst(Mailbox mbox) throws ServiceException
/*      */     {
/*  686 */       return (this.convId != 0) || (this.tags.contains(mbox.getFlagById(Flag.ID_UNREAD)));
/*      */     }
/*      */     
/*      */     public void setTypes(Set<MailItem.Type> set)
/*      */     {
/*  691 */       this.types.clear();
/*  692 */       this.types.addAll(set);
/*  693 */       if (this.types.isEmpty()) {
/*  694 */         this.noResults = true;
/*      */       }
/*      */     }
/*      */     
/*      */     void addItemIdClause(Integer itemId, boolean truth) {
/*  699 */       if (truth) {
/*  700 */         if (!this.itemIds.contains(itemId))
/*      */         {
/*      */ 
/*      */ 
/*  704 */           if ((this.prohibitedItemIds == null) || (!this.prohibitedItemIds.contains(itemId))) {
/*  705 */             this.itemIds.add(itemId);
/*      */           }
/*      */         }
/*      */       }
/*  709 */       else if (!this.prohibitedItemIds.contains(itemId))
/*      */       {
/*      */ 
/*      */ 
/*  713 */         if ((this.itemIds != null) && (this.itemIds.contains(itemId))) {
/*  714 */           this.itemIds.remove(itemId);
/*      */         }
/*  716 */         this.prohibitedItemIds.add(itemId);
/*      */       }
/*      */     }
/*      */     
/*      */     void addRemoteItemIdClause(ItemId itemId, boolean truth)
/*      */     {
/*  722 */       if (truth) {
/*  723 */         if (!this.remoteItemIds.contains(itemId))
/*      */         {
/*      */ 
/*      */ 
/*  727 */           if ((this.prohibitedRemoteItemIds == null) || (!this.prohibitedRemoteItemIds.contains(itemId))) {
/*  728 */             this.remoteItemIds.add(itemId);
/*      */           }
/*      */         }
/*      */       }
/*  732 */       else if (!this.prohibitedRemoteItemIds.contains(itemId))
/*      */       {
/*      */ 
/*      */ 
/*  736 */         if ((this.remoteItemIds != null) && (this.remoteItemIds.contains(itemId))) {
/*  737 */           this.remoteItemIds.remove(itemId);
/*      */         }
/*  739 */         this.prohibitedRemoteItemIds.add(itemId);
/*      */       }
/*      */     }
/*      */     
/*      */     public void addDateRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool)
/*      */     {
/*  745 */       if ((min < 0L) && (max < 0L)) {
/*  746 */         return;
/*      */       }
/*  748 */       this.ranges.put(DbSearchConstraints.RangeType.DATE, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addMDateRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  752 */       if ((min < 0L) && (max < 0L)) {
/*  753 */         return;
/*      */       }
/*  755 */       this.ranges.put(DbSearchConstraints.RangeType.MDATE, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addCalStartDateRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  759 */       if ((min < 0L) && (max < 0L)) {
/*  760 */         return;
/*      */       }
/*  762 */       this.ranges.put(DbSearchConstraints.RangeType.CAL_START_DATE, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addCalEndDateRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  766 */       if ((min < 0L) && (max < 0L)) {
/*  767 */         return;
/*      */       }
/*  769 */       this.ranges.put(DbSearchConstraints.RangeType.CAL_END_DATE, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addModSeqRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  773 */       if ((min < 0L) && (max < 0L)) {
/*  774 */         return;
/*      */       }
/*  776 */       this.ranges.put(DbSearchConstraints.RangeType.MODSEQ, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addConvCountRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  780 */       if ((min < 0L) && (max < 0L)) {
/*  781 */         return;
/*      */       }
/*  783 */       this.ranges.put(DbSearchConstraints.RangeType.CONV_COUNT, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addSizeRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/*  787 */       if ((min < 0L) && (max < 0L)) {
/*  788 */         return;
/*      */       }
/*  790 */       this.ranges.put(DbSearchConstraints.RangeType.SIZE, new DbSearchConstraints.NumericRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addSubjectRange(String min, boolean minInclusive, String max, boolean maxInclusive, boolean bool) {
/*  794 */       if ((min == null) && (max == null)) {
/*  795 */         return;
/*      */       }
/*  797 */       this.ranges.put(DbSearchConstraints.RangeType.SUBJECT, new DbSearchConstraints.StringRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     public void addSenderRange(String min, boolean minInclusive, String max, boolean maxInclusive, boolean bool) {
/*  801 */       if ((min == null) && (max == null)) {
/*  802 */         return;
/*      */       }
/*  804 */       this.ranges.put(DbSearchConstraints.RangeType.SENDER, new DbSearchConstraints.StringRange(min, minInclusive, max, maxInclusive, bool));
/*      */     }
/*      */     
/*      */     void setCursorRange(String min, boolean minInclusive, String max, boolean maxInclusive, SortBy sort) {
/*  808 */       assert (this.cursorRange == null) : this.cursorRange;
/*  809 */       this.cursorRange = new DbSearchConstraints.CursorRange(min, minInclusive, max, maxInclusive, sort);
/*      */     }
/*      */     
/*      */     void addConvId(int cid, boolean truth)
/*      */     {
/*  814 */       if (truth) {
/*  815 */         if (this.prohibitedConvIds.contains(Integer.valueOf(cid))) {
/*  816 */           this.noResults = true;
/*      */         }
/*      */         
/*  819 */         if (this.convId == 0) {
/*  820 */           this.convId = cid;
/*      */         } else {
/*  822 */           ZimbraLog.search.debug("Query requested two conflicting convIDs, this is now a no-results-query");
/*  823 */           this.convId = Integer.MAX_VALUE;
/*  824 */           this.noResults = true;
/*      */         }
/*      */       } else {
/*  827 */         if (this.convId == cid) {
/*  828 */           this.noResults = true;
/*      */         }
/*  830 */         this.prohibitedConvIds.add(Integer.valueOf(cid));
/*      */       }
/*      */     }
/*      */     
/*      */     void addRemoteConvId(ItemId cid, boolean truth)
/*      */     {
/*  836 */       if (truth) {
/*  837 */         if (this.prohibitedRemoteConvIds.contains(cid)) {
/*  838 */           this.noResults = true;
/*      */         }
/*      */         
/*  841 */         if (this.remoteConvId == null) {
/*  842 */           this.remoteConvId = cid;
/*      */         } else {
/*  844 */           ZimbraLog.search.debug("Query requested two conflicting Remote convIDs, this is now a no-results-query");
/*  845 */           this.remoteConvId = new ItemId(cid.getAccountId(), Integer.MAX_VALUE);
/*  846 */           this.noResults = true;
/*      */         }
/*      */       } else {
/*  849 */         if (this.remoteConvId.equals(cid)) {
/*  850 */           this.noResults = true;
/*      */         }
/*  852 */         this.prohibitedRemoteConvIds.add(cid);
/*      */       }
/*      */     }
/*      */     
/*      */     void addInRemoteFolder(ItemId id, String subfolderPath, boolean includeSubfolders, boolean bool) {
/*  857 */       if (bool) {
/*  858 */         if (((!this.remoteFolders.isEmpty()) && (!this.remoteFolders.contains(id))) || (this.excludeRemoteFolders.contains(id))) {
/*  859 */           ZimbraLog.search.debug("AND of conflicting remote folders, no-results-query");
/*  860 */           this.noResults = true;
/*      */         }
/*  862 */         this.remoteFolders.clear();
/*  863 */         this.remoteFolders.add(new DbSearchConstraints.RemoteFolderDescriptor(id, subfolderPath, includeSubfolders));
/*  864 */         forceHasSpamTrashSetting();
/*      */       } else {
/*  866 */         if (this.remoteFolders.contains(id)) {
/*  867 */           this.remoteFolders.remove(id);
/*  868 */           if (this.remoteFolders.isEmpty()) {
/*  869 */             ZimbraLog.search.debug("AND of conflicting remote folders, no-results-query");
/*  870 */             this.noResults = true;
/*      */           }
/*      */         }
/*  873 */         this.excludeRemoteFolders.add(new DbSearchConstraints.RemoteFolderDescriptor(id, subfolderPath, includeSubfolders));
/*      */       }
/*      */     }
/*      */     
/*      */     void addInFolder(Folder folder, boolean bool) {
/*  878 */       if (bool) {
/*  879 */         if (((!this.folders.isEmpty()) && (!this.folders.contains(folder))) || (this.excludeFolders.contains(folder))) {
/*  880 */           ZimbraLog.search.debug("AND of conflicting folders, no-results-query");
/*  881 */           this.noResults = true;
/*      */         }
/*  883 */         this.folders.clear();
/*  884 */         this.folders.add(folder);
/*  885 */         forceHasSpamTrashSetting();
/*      */       } else {
/*  887 */         if (this.folders.contains(folder)) {
/*  888 */           this.folders.remove(folder);
/*  889 */           if (this.folders.isEmpty()) {
/*  890 */             ZimbraLog.search.debug("AND of conflicting folders, no-results-query");
/*  891 */             this.noResults = true;
/*      */           }
/*      */         }
/*  894 */         this.excludeFolders.add(folder);
/*      */         
/*  896 */         int fid = folder.getId();
/*  897 */         if ((fid == 3) || (fid == 4)) {
/*  898 */           forceHasSpamTrashSetting();
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*      */ 
/*      */     void addAnyFolder(boolean bool)
/*      */     {
/*  906 */       forceHasSpamTrashSetting();
/*      */       
/*  908 */       if (!bool)
/*      */       {
/*      */ 
/*  911 */         ZimbraLog.search.debug("addAnyFolderClause(FALSE) called -- changing to no-results-query.");
/*  912 */         this.noResults = true;
/*      */       }
/*      */     }
/*      */     
/*      */     public void addTag(Tag tag, boolean bool) {
/*  917 */       if (bool) {
/*  918 */         if (this.excludeTags.contains(tag)) {
/*  919 */           this.noResults = true;
/*      */         }
/*  921 */         this.tags.add(tag);
/*      */       } else {
/*  923 */         if (this.tags.contains(tag)) {
/*  924 */           this.noResults = true;
/*      */         }
/*  926 */         this.excludeTags.add(tag);
/*      */       }
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/*  932 */       return toQueryString(new StringBuilder()).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class Intersection implements DbSearchConstraints
/*      */   {
/*  938 */     private List<DbSearchConstraints> children = new ArrayList();
/*      */     
/*      */     public boolean isEmpty()
/*      */     {
/*  942 */       for (DbSearchConstraints child : getChildren()) {
/*  943 */         if (!child.isEmpty()) {
/*  944 */           return false;
/*      */         }
/*      */       }
/*  947 */       return true;
/*      */     }
/*      */     
/*      */     public Intersection optimize()
/*      */     {
/*  952 */       for (int i = 0; i < this.children.size(); i++) {
/*  953 */         this.children.set(i, ((DbSearchConstraints)this.children.get(i)).optimize());
/*      */       }
/*  955 */       return this;
/*      */     }
/*      */     
/*      */     public List<DbSearchConstraints> getChildren()
/*      */     {
/*  960 */       return this.children;
/*      */     }
/*      */     
/*      */     public DbSearchConstraints.Leaf toLeaf()
/*      */     {
/*  965 */       return null;
/*      */     }
/*      */     
/*      */     public Object clone()
/*      */     {
/*      */       Intersection result;
/*      */       try {
/*  972 */         result = (Intersection)super.clone();
/*      */       } catch (CloneNotSupportedException e) {
/*  974 */         return null;
/*      */       }
/*      */       
/*  977 */       result.children = new ArrayList();
/*  978 */       for (DbSearchConstraints child : this.children) {
/*  979 */         result.children.add((DbSearchConstraints)child.clone());
/*      */       }
/*  981 */       return result;
/*      */     }
/*      */     
/*      */     DbSearchConstraints.Leaf getLeafChild() {
/*  985 */       for (DbSearchConstraints child : this.children) {
/*  986 */         if ((child instanceof DbSearchConstraints.Leaf)) {
/*  987 */           return (DbSearchConstraints.Leaf)child;
/*      */         }
/*      */       }
/*  990 */       DbSearchConstraints.Leaf leaf = new DbSearchConstraints.Leaf();
/*  991 */       this.children.add(leaf);
/*  992 */       return leaf;
/*      */     }
/*      */     
/*      */     public DbSearchConstraints and(DbSearchConstraints other)
/*      */     {
/*  997 */       if ((other instanceof DbSearchConstraints.Leaf)) {
/*  998 */         DbSearchConstraints.Leaf leaf = (DbSearchConstraints.Leaf)other;
/*  999 */         getLeafChild().and(leaf);
/* 1000 */       } else if ((other instanceof Intersection)) {
/* 1001 */         for (DbSearchConstraints child : ((Intersection)other).children) {
/* 1002 */           if ((child instanceof DbSearchConstraints.Leaf)) {
/* 1003 */             DbSearchConstraints c = getLeafChild().and(child);
/* 1004 */             assert (c == this);
/*      */           } else {
/* 1006 */             this.children.add(child);
/*      */           }
/*      */         }
/* 1009 */       } else if ((other instanceof DbSearchConstraints.Union)) {
/* 1010 */         this.children.add(other);
/*      */       }
/* 1012 */       return this;
/*      */     }
/*      */     
/*      */     public DbSearchConstraints or(DbSearchConstraints other)
/*      */     {
/* 1017 */       if ((other instanceof DbSearchConstraints.Union)) {
/* 1018 */         return other.or(other);
/*      */       }
/* 1020 */       DbSearchConstraints top = new DbSearchConstraints.Union();
/* 1021 */       return top.or(this).or(other);
/*      */     }
/*      */     
/*      */     public void ensureSpamTrashSetting(Mailbox mbox, List<Folder> excludeFolders)
/*      */       throws ServiceException
/*      */     {
/* 1027 */       DbSearchConstraints c = getLeafChild();
/* 1028 */       c.ensureSpamTrashSetting(mbox, excludeFolders);
/*      */     }
/*      */     
/*      */     public boolean hasSpamTrashSetting()
/*      */     {
/* 1033 */       for (DbSearchConstraints child : this.children) {
/* 1034 */         if (child.hasSpamTrashSetting()) {
/* 1035 */           return true;
/*      */         }
/*      */       }
/* 1038 */       return false;
/*      */     }
/*      */     
/*      */     public void forceHasSpamTrashSetting()
/*      */     {
/* 1043 */       for (DbSearchConstraints child : this.children) {
/* 1044 */         if (!child.hasSpamTrashSetting()) {
/* 1045 */           child.forceHasSpamTrashSetting();
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*      */     public boolean hasNoResults()
/*      */     {
/* 1052 */       for (DbSearchConstraints child : this.children) {
/* 1053 */         if (child.hasNoResults()) {
/* 1054 */           return true;
/*      */         }
/*      */       }
/* 1057 */       return false;
/*      */     }
/*      */     
/*      */     public boolean tryDbFirst(Mailbox mbox)
/*      */     {
/* 1062 */       return false;
/*      */     }
/*      */     
/*      */     public void setTypes(Set<MailItem.Type> types)
/*      */     {
/* 1067 */       for (DbSearchConstraints child : this.children) {
/* 1068 */         child.setTypes(types);
/*      */       }
/*      */     }
/*      */     
/*      */     public StringBuilder toQueryString(StringBuilder out)
/*      */     {
/* 1074 */       boolean first = true;
/* 1075 */       for (DbSearchConstraints child : this.children) {
/* 1076 */         if (!first) {
/* 1077 */           out.append(" AND ");
/*      */         }
/* 1079 */         out.append('(');
/* 1080 */         child.toQueryString(out);
/* 1081 */         out.append(')');
/* 1082 */         first = false;
/*      */       }
/* 1084 */       return out;
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/* 1089 */       return toQueryString(new StringBuilder()).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class Union implements DbSearchConstraints {
/* 1094 */     private List<DbSearchConstraints> children = new ArrayList();
/*      */     
/*      */     public boolean isEmpty()
/*      */     {
/* 1098 */       for (DbSearchConstraints child : getChildren()) {
/* 1099 */         if (!child.isEmpty()) {
/* 1100 */           return false;
/*      */         }
/*      */       }
/* 1103 */       return true;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */     private DbSearchConstraints combineFolderConstraints()
/*      */     {
/* 1113 */       List<DbSearchConstraints.Leaf> onlyFolderConstraints = new ArrayList();
/* 1114 */       List<DbSearchConstraints.Leaf> otherConstraints = new ArrayList();
/* 1115 */       for (DbSearchConstraints child : getChildren())
/*      */       {
/* 1117 */         if (!(child instanceof DbSearchConstraints.Leaf)) {
/* 1118 */           return this;
/*      */         }
/*      */         
/*      */ 
/* 1122 */         DbSearchConstraints.Leaf leaf = child.toLeaf();
/* 1123 */         if ((!leaf.folders.isEmpty()) && (leaf.excludeFolders.isEmpty()) && (leaf.tags.isEmpty()) && (leaf.excludeTags.isEmpty()) && (leaf.types.isEmpty()) && (leaf.typesFactoredOut) && (leaf.convId == 0) && (leaf.prohibitedConvIds.isEmpty()) && (leaf.itemIds.isEmpty()) && (leaf.prohibitedItemIds.isEmpty()) && (leaf.hasIndexId == null) && (!leaf.excludeHasRecipients) && (leaf.ranges.isEmpty()) && (leaf.cursorRange == null))
/*      */         {
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/* 1137 */           onlyFolderConstraints.add(leaf);
/*      */         } else {
/* 1139 */           otherConstraints.add(leaf);
/*      */         }
/*      */       }
/*      */       
/* 1143 */       DbSearchConstraints.Leaf folderLeaf = new DbSearchConstraints.Leaf();
/* 1144 */       folderLeaf.typesFactoredOut = true;
/* 1145 */       for (DbSearchConstraints.Leaf leaf : onlyFolderConstraints) {
/* 1146 */         folderLeaf.folders.addAll(leaf.folders);
/*      */       }
/*      */       
/*      */ 
/* 1150 */       if (onlyFolderConstraints.size() == this.children.size()) {
/* 1151 */         return folderLeaf;
/*      */       }
/* 1153 */       Union newOr = new Union();
/* 1154 */       newOr.children.add(folderLeaf);
/* 1155 */       for (DbSearchConstraints.Leaf otherLeaf : otherConstraints) {
/* 1156 */         newOr.children.add(otherLeaf);
/*      */       }
/* 1158 */       return newOr;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     public DbSearchConstraints optimize()
/*      */     {
/* 1166 */       HashMap<Set<MailItem.Type>, ArrayList<DbSearchConstraints.Leaf>> byValue = new HashMap();
/*      */       
/* 1168 */       for (int i = 0; i < this.children.size(); i++) {
/* 1169 */         DbSearchConstraints child = (DbSearchConstraints)this.children.get(i);
/* 1170 */         if ((child instanceof DbSearchConstraints.Leaf)) {
/* 1171 */           DbSearchConstraints.Leaf leaf = child.toLeaf();
/* 1172 */           Set<MailItem.Type> types = leaf.types;
/* 1173 */           if (!ListUtil.isEmpty(types)) {
/* 1174 */             if (!byValue.containsKey(types)) {
/* 1175 */               ArrayList<DbSearchConstraints.Leaf> newArray = new ArrayList();
/* 1176 */               byValue.put(types, newArray);
/*      */             }
/* 1178 */             ((ArrayList)byValue.get(types)).add(leaf);
/*      */           }
/*      */         } else {
/* 1181 */           this.children.set(i, child.optimize());
/*      */         }
/*      */       }
/*      */       
/*      */ 
/* 1186 */       DbSearchConstraints.Intersection newAnd = new DbSearchConstraints.Intersection();
/* 1187 */       boolean optimized = false;
/* 1188 */       for (Set<MailItem.Type> types : byValue.keySet()) {
/* 1189 */         ArrayList<DbSearchConstraints.Leaf> nodes = (ArrayList)byValue.get(types);
/* 1190 */         if (nodes.size() > 2) {
/* 1191 */           optimized = true;
/* 1192 */           Union newOr = new Union();
/* 1193 */           for (DbSearchConstraints.Leaf leaf : nodes) {
/* 1194 */             DbSearchConstraints.Leaf cloned = leaf.clone();
/* 1195 */             cloned.types.clear();
/* 1196 */             cloned.typesFactoredOut = true;
/* 1197 */             newOr.children.add(cloned);
/* 1198 */             this.children.remove(leaf);
/*      */           }
/* 1200 */           DbSearchConstraints.Intersection.access$100(newAnd).add(newOr.combineFolderConstraints());
/*      */           
/* 1202 */           DbSearchConstraints.Leaf factoredLeaf = new DbSearchConstraints.Leaf();
/* 1203 */           factoredLeaf.setTypes(types);
/* 1204 */           DbSearchConstraints.Intersection.access$100(newAnd).add(0, factoredLeaf);
/*      */         }
/* 1206 */         this.children.add(newAnd);
/*      */       }
/* 1208 */       if (!optimized)
/* 1209 */         return this;
/* 1210 */       if (this.children.size() == 1) {
/* 1211 */         return (DbSearchConstraints)this.children.get(0);
/*      */       }
/* 1213 */       return this;
/*      */     }
/*      */     
/*      */ 
/*      */     public List<DbSearchConstraints> getChildren()
/*      */     {
/* 1219 */       return this.children;
/*      */     }
/*      */     
/*      */     public DbSearchConstraints.Leaf toLeaf()
/*      */     {
/* 1224 */       return null;
/*      */     }
/*      */     
/*      */     public Object clone()
/*      */     {
/*      */       Union result;
/*      */       try {
/* 1231 */         result = (Union)super.clone();
/*      */       } catch (CloneNotSupportedException e) {
/* 1233 */         return null;
/*      */       }
/* 1235 */       result.children = new ArrayList();
/* 1236 */       for (DbSearchConstraints child : this.children) {
/* 1237 */         result.children.add((DbSearchConstraints)child.clone());
/*      */       }
/* 1239 */       return result;
/*      */     }
/*      */     
/*      */     public DbSearchConstraints and(DbSearchConstraints other)
/*      */     {
/* 1244 */       if ((other instanceof DbSearchConstraints.Intersection)) {
/* 1245 */         return other.and(this);
/*      */       }
/* 1247 */       DbSearchConstraints top = new DbSearchConstraints.Intersection();
/* 1248 */       return top.and(this).and(other);
/*      */     }
/*      */     
/*      */ 
/*      */     public DbSearchConstraints or(DbSearchConstraints other)
/*      */     {
/* 1254 */       if ((other instanceof Union)) {
/* 1255 */         this.children.addAll(((Union)other).children);
/*      */       } else {
/* 1257 */         this.children.add(other);
/*      */       }
/* 1259 */       return this;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */     public void ensureSpamTrashSetting(Mailbox mbox, List<Folder> excludeFolders)
/*      */       throws ServiceException
/*      */     {
/* 1273 */       for (DbSearchConstraints child : this.children) {
/* 1274 */         child.ensureSpamTrashSetting(mbox, excludeFolders);
/*      */       }
/*      */     }
/*      */     
/*      */     public boolean hasSpamTrashSetting()
/*      */     {
/* 1280 */       for (DbSearchConstraints child : this.children) {
/* 1281 */         if (!child.hasSpamTrashSetting()) {
/* 1282 */           return false;
/*      */         }
/*      */       }
/* 1285 */       return true;
/*      */     }
/*      */     
/*      */     public void forceHasSpamTrashSetting()
/*      */     {
/* 1290 */       for (DbSearchConstraints child : this.children) {
/* 1291 */         if (!child.hasSpamTrashSetting()) {
/* 1292 */           child.forceHasSpamTrashSetting();
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*      */     public boolean hasNoResults()
/*      */     {
/* 1299 */       for (DbSearchConstraints child : this.children) {
/* 1300 */         if (!child.hasNoResults()) {
/* 1301 */           return false;
/*      */         }
/*      */       }
/* 1304 */       return true;
/*      */     }
/*      */     
/*      */     public boolean tryDbFirst(Mailbox mbox)
/*      */     {
/* 1309 */       return false;
/*      */     }
/*      */     
/*      */     public void setTypes(Set<MailItem.Type> types)
/*      */     {
/* 1314 */       for (DbSearchConstraints child : this.children) {
/* 1315 */         child.setTypes(types);
/*      */       }
/*      */     }
/*      */     
/*      */     public StringBuilder toQueryString(StringBuilder out)
/*      */     {
/* 1321 */       boolean first = true;
/* 1322 */       if (this.children.size() > 1) {
/* 1323 */         out.append('(');
/*      */       }
/* 1325 */       for (DbSearchConstraints child : this.children) {
/* 1326 */         if (!first) {
/* 1327 */           out.append(" OR ");
/*      */         }
/* 1329 */         out.append('(');
/* 1330 */         child.toQueryString(out);
/* 1331 */         out.append(')');
/* 1332 */         first = false;
/*      */       }
/* 1334 */       if (this.children.size() > 1) {
/* 1335 */         out.append(')');
/*      */       }
/* 1337 */       return out;
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/* 1342 */       return toQueryString(new StringBuilder()).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static abstract class Range implements Cloneable {
/*      */     public final boolean bool;
/*      */     public final boolean minInclusive;
/*      */     public final boolean maxInclusive;
/*      */     
/*      */     Range(boolean minInclusive, boolean maxInclusive, boolean bool) {
/* 1352 */       this.minInclusive = minInclusive;
/* 1353 */       this.maxInclusive = maxInclusive;
/* 1354 */       this.bool = bool;
/*      */     }
/*      */     
/*      */     abstract StringBuilder toQueryString(String paramString, StringBuilder paramStringBuilder);
/*      */     
/*      */     public abstract Range clone();
/*      */   }
/*      */   
/*      */   public static final class StringRange extends DbSearchConstraints.Range
/*      */   {
/*      */     public final String min;
/*      */     public final String max;
/*      */     
/*      */     public StringRange(String min, boolean minInclusive, String max, boolean maxInclusive, boolean bool)
/*      */     {
/* 1369 */       super(maxInclusive, bool);
/* 1370 */       this.min = min;
/* 1371 */       this.max = max;
/*      */     }
/*      */     
/*      */     public StringRange clone()
/*      */     {
/* 1376 */       return new StringRange(this.min, this.minInclusive, this.max, this.maxInclusive, this.bool);
/*      */     }
/*      */     
/*      */     public boolean equals(Object o)
/*      */     {
/* 1381 */       if ((o instanceof StringRange)) {
/* 1382 */         StringRange other = (StringRange)o;
/* 1383 */         return (Objects.equal(other.min, this.min)) && (other.minInclusive == this.minInclusive) && (Objects.equal(other.max, this.max)) && (other.maxInclusive == this.maxInclusive) && (other.bool == this.bool);
/*      */       }
/*      */       
/* 1386 */       return false;
/*      */     }
/*      */     
/*      */ 
/*      */     public int hashCode()
/*      */     {
/* 1392 */       return Objects.hashCode(new Object[] { Boolean.valueOf(this.bool), this.min, Boolean.valueOf(this.minInclusive), this.max, Boolean.valueOf(this.maxInclusive) });
/*      */     }
/*      */     
/*      */     StringBuilder toQueryString(String name, StringBuilder out)
/*      */     {
/* 1397 */       if (!this.bool) {
/* 1398 */         out.append('-');
/*      */       }
/* 1400 */       out.append(name).append(":(");
/* 1401 */       if (this.min != null) {
/* 1402 */         out.append('>');
/* 1403 */         if (this.minInclusive) {
/* 1404 */           out.append('=');
/*      */         }
/* 1406 */         out.append('"').append(this.min).append('"');
/*      */       }
/* 1408 */       if (this.max != null) {
/* 1409 */         if (this.min != null) {
/* 1410 */           out.append(' ');
/*      */         }
/* 1412 */         out.append('<');
/* 1413 */         if (this.maxInclusive) {
/* 1414 */           out.append('=');
/*      */         }
/* 1416 */         out.append('"').append(this.max).append('"');
/*      */       }
/* 1418 */       out.append(')');
/* 1419 */       return out;
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/* 1424 */       return toQueryString("RANGE", new StringBuilder()).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static enum RangeType {
/* 1429 */     DATE("DATE"),  MDATE("MDATE"),  MODSEQ("MODSEQ"),  SIZE("SIZE"),  CONV_COUNT("CONV-COUNT"), 
/* 1430 */     CAL_START_DATE("APPT-START"),  CAL_END_DATE("APPT-END"),  SUBJECT("SUBJECT"),  SENDER("FROM");
/*      */     
/*      */     private final String query;
/*      */     
/*      */     private RangeType(String query) {
/* 1435 */       this.query = query;
/*      */     }
/*      */     
/*      */     String toQuery() {
/* 1439 */       return this.query;
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class NumericRange extends DbSearchConstraints.Range
/*      */   {
/*      */     public final long min;
/*      */     public final long max;
/*      */     
/*      */     public NumericRange(long min, boolean minInclusive, long max, boolean maxInclusive, boolean bool) {
/* 1449 */       super(maxInclusive, bool);
/* 1450 */       this.min = min;
/* 1451 */       this.max = max;
/*      */     }
/*      */     
/*      */     public NumericRange clone()
/*      */     {
/* 1456 */       return new NumericRange(this.min, this.minInclusive, this.max, this.maxInclusive, this.bool);
/*      */     }
/*      */     
/*      */     public boolean equals(Object o)
/*      */     {
/* 1461 */       if ((o instanceof NumericRange)) {
/* 1462 */         NumericRange other = (NumericRange)o;
/* 1463 */         return (other.min == this.min) && (other.minInclusive == this.minInclusive) && (other.max == this.max) && (other.maxInclusive == this.maxInclusive) && (other.bool == this.bool);
/*      */       }
/*      */       
/* 1466 */       return false;
/*      */     }
/*      */     
/*      */ 
/*      */     public int hashCode()
/*      */     {
/* 1472 */       return Objects.hashCode(new Object[] { Boolean.valueOf(this.bool), Long.valueOf(this.min), Boolean.valueOf(this.minInclusive), Long.valueOf(this.max), Boolean.valueOf(this.maxInclusive) });
/*      */     }
/*      */     
/*      */     StringBuilder toQueryString(String name, StringBuilder out)
/*      */     {
/* 1477 */       if (!this.bool) {
/* 1478 */         out.append('-');
/*      */       }
/* 1480 */       out.append(name).append(':');
/*      */       
/* 1482 */       if ((this.min >= 0L) && (this.minInclusive) && (this.maxInclusive) && (this.min == this.max)) {
/* 1483 */         out.append(this.min);
/*      */       } else {
/* 1485 */         out.append('(');
/* 1486 */         if (this.min >= 0L) {
/* 1487 */           out.append('>');
/* 1488 */           if (this.minInclusive) {
/* 1489 */             out.append('=');
/*      */           }
/* 1491 */           out.append(this.min);
/*      */         }
/* 1493 */         if (this.max >= 0L) {
/* 1494 */           if (this.min >= 0L) {
/* 1495 */             out.append(' ');
/*      */           }
/* 1497 */           out.append('<');
/* 1498 */           if (this.maxInclusive) {
/* 1499 */             out.append('=');
/*      */           }
/* 1501 */           out.append(this.max);
/*      */         }
/* 1503 */         out.append(')');
/*      */       }
/* 1505 */       return out;
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/* 1510 */       return toQueryString("RANGE", new StringBuilder()).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class CursorRange {
/*      */     public final String min;
/*      */     public final boolean minInclusive;
/*      */     public final String max;
/*      */     public final boolean maxInclusive;
/*      */     public final SortBy sortBy;
/*      */     
/*      */     public CursorRange(String min, boolean minInclusive, String max, boolean maxInclusive, SortBy sort) {
/* 1522 */       this.min = min;
/* 1523 */       this.minInclusive = minInclusive;
/* 1524 */       this.max = max;
/* 1525 */       this.maxInclusive = maxInclusive;
/* 1526 */       this.sortBy = sort;
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/* 1531 */       return Objects.toStringHelper(this).add("min", this.min).add("max", this.max).add("sort", this.sortBy).toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class RemoteFolderDescriptor {
/*      */     private final ItemId folderId;
/*      */     private String subfolderPath;
/*      */     private final boolean includeSubfolders;
/*      */     
/*      */     public RemoteFolderDescriptor(ItemId iidFolder, String subpath, boolean includeSubfolders) {
/* 1541 */       this.includeSubfolders = includeSubfolders;
/* 1542 */       this.folderId = iidFolder;
/* 1543 */       this.subfolderPath = subpath;
/* 1544 */       if (this.subfolderPath == null)
/* 1545 */         this.subfolderPath = "";
/*      */     }
/*      */     
/*      */     public ItemId getFolderId() {
/* 1549 */       return this.folderId;
/*      */     }
/*      */     
/* 1552 */     public String getSubfolderPath() { return this.subfolderPath; }
/*      */     
/*      */     public boolean getIncludeSubfolders()
/*      */     {
/* 1556 */       return this.includeSubfolders;
/*      */     }
/*      */     
/*      */     public int hashCode()
/*      */     {
/* 1561 */       int PRIME = 31;
/* 1562 */       int result = 1;
/* 1563 */       result = 31 * result + (this.folderId == null ? 0 : this.folderId.hashCode());
/* 1564 */       result = 31 * result + (this.subfolderPath == null ? 0 : this.subfolderPath.hashCode());
/* 1565 */       return result;
/*      */     }
/*      */     
/*      */     public boolean equals(Object obj)
/*      */     {
/* 1570 */       if (this == obj) {
/* 1571 */         return true;
/*      */       }
/* 1573 */       if ((obj instanceof RemoteFolderDescriptor)) {
/* 1574 */         RemoteFolderDescriptor other = (RemoteFolderDescriptor)obj;
/* 1575 */         if (other.includeSubfolders != this.includeSubfolders) {
/* 1576 */           return false;
/*      */         }
/* 1578 */         if (this.folderId == null) {
/* 1579 */           if (other.folderId != null) {
/* 1580 */             return false;
/*      */           }
/* 1582 */         } else if (!this.folderId.equals(other.folderId)) {
/* 1583 */           return false;
/*      */         }
/* 1585 */         if (this.subfolderPath == null) {
/* 1586 */           if (other.subfolderPath != null) {
/* 1587 */             return false;
/*      */           }
/* 1589 */         } else if (!this.subfolderPath.equals(other.subfolderPath)) {
/* 1590 */           return false;
/*      */         }
/* 1592 */         return true;
/*      */       }
/* 1594 */       return false;
/*      */     }
/*      */     
/*      */ 
/*      */     public String toString()
/*      */     {
/* 1600 */       return this.folderId + "/" + this.subfolderPath + (this.includeSubfolders ? "..." : "");
/*      */     }
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/index/DbSearchConstraints.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */